<template>
  <BasicModal
    v-bind="$attrs"
    width="90%"
    @ok="handleSubmint"
    okText="同步更新"
    :confirmLoading="isSubmintLoading"
    :closeFunc="handleCloseFunc"
    cancelText="关闭"
    @register="register"
    :title="modalTitle"
    @visible-change="handleVisibleChange"
  >
    <div class="tag">
      <div class="main-nav">
        <BasicTree
          title=""
          ref="treeRef"
          :treeData="treeDataPro"
          :actionList="actionList"
          :fieldNames="{ key: 'Key', title: 'Name', children: 'Children' }"
          :onSelect="handleTreeSelect"
        />
      </div>
      <div class="main-content">
        <BasicTable
          :title="BasicTableTitle"
          :columns="columns"
          :loading="tableLoading"
          :dataSource="tableData"
          :canResize="false"
          :showIndexColumn="false"
          :striped="true"
          :bordered="true"
          :pagination="false"
          :actionColumn="actionColumn"
          @columns-change="handleColumnChange"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'action'">
              <TableAction
                :actions="[
                  {
                    label: '编辑',
                    icon: 'ant-design:edit-outlined',
                    disabled: +record.TagType === 2,
                    onClick: handleEdit.bind(null, record),
                  },
                  {
                    label: '编译器',
                    icon: 'ant-design:code-outlined',
                    onClick: handleCode.bind(null, record),
                  },
                  {
                    label: '删除',
                    icon: 'ant-design:delete-outlined',
                    disabled: +record.TagType === 2,
                    onClick: handleDelete.bind(null, record),
                  },
                  {
                    label: '复制',
                    icon: 'ant-design:copy-outlined',
                    onClick: handleCopy.bind(null, record),
                  },
                ]"
              />
            </template>
          </template>
          <template #toolbar>
            <a-button v-if="isShowAdd" type="primary" @click="handleAdd"> 新增 </a-button>
          </template>
        </BasicTable>
        <div class="flex py-2 items-center justify-end pagination-box">
          <a-pagination
            :show-total="(total) => `共 ${total} 条数据`"
            showSizeChanger
            size="small"
            :current="paginationInfo.data.current"
            :pageSize="paginationInfo.data.pageSize"
            :total="paginationInfo.data.total"
            @change="handlePageChange"
          />
        </div>
      </div>
      <!-- 驱动的表单弹窗 -->
      <modelByDrive
        :formType="formType"
        @register="registerByDrive"
        type="template"
        @submit-success="handelUpdateTree"
      />
      <!-- 分组的表单弹窗 -->
      <modelByGroup
        :formType="formType"
        @register="registerByGroup"
        type="template"
        @submit-success="handelUpdateTree"
      />
      <!-- 表单弹窗 -->
      <modelByDetail
        :info="tagFormInfo"
        :typeOptions="typeOptions"
        :addressExtend="addressExtend"
        :driverregesterOPtions="driverregesterOPtions"
        :readWriteModeOptions="readWriteModeOptions"
        @register="registerByDetail"
        @submit-success="handleUpdateTable"
      />
      <modelByCodemirror @register="registerByCode" @get-code="handleGetCode" :info="tagFormInfo" />
    </div>
  </BasicModal>
</template>

<script lang="ts" setup>
  import { BasicTable, ColumnChangeParam, TableAction } from '/@/components/Table';

  import { BasicColumn } from '/@/components/Table/src/types/table';

  import { cloneDeep } from 'lodash-es';
  import { Pagination } from 'ant-design-vue';
  import { BasicModal, useModal } from '/@/components/Modal';
  import modelByDrive from '/@/views/project/tag/components/modelByDrive.vue';
  import modelByGroup from '/@/views/project/tag/components/modelByGroup.vue';

  import modelByCodemirror from '/@/components/codemirror/index.vue';
  import modelByDetail from '/@/views/project/tag/components/modelByDetail.vue';

  import { useMessage } from '/@/hooks/web/useMessage';
  import { reactive, ref, unref, nextTick, h, computed, watch } from 'vue';

  import { BasicTree, TreeActionType, TreeActionItem } from '/@/components/Tree/index';
  // import { downloadByData, getFileHash } from '/@/utils/file/download';
  import { DeleteOutlined, EditOutlined, PlusOutlined } from '@ant-design/icons-vue';

  import {
    gettemplatetree,
    delDriverInfo,
    delGroupInfo,
    gettemplatetag,
    getDataType,
    deltemplatetag,
    addtemplatetag,
    updatetemplatetag,
    getReadWriteMode,
    getdriverregester,
    gettemplat,
    updatetemplate,
    addtemplategroup,
    updatetemplategroup,
    gettemplategroup,
    savetemplateandupdate,
  } from '/@/api/tag/index';

  import { useI18n } from '/@/hooks/web/useI18n';
  const APagination = Pagination;
  const props = defineProps({
    info: {
      type: Object,
      default: () => {},
    },
  });
  // 控制变量新增\编辑 表单里面的"关联变量"操作模式 0：地址为输入模式 1：时从列表获取
  let addressExtend = ref(0);
  // 分页信息
  let paginationInfo = reactive({
    data: {
      pageSize: 50,
      total: 0,
      current: 1,
    },
  });
  let templateInfo = {};
  let formType = reactive<any>({
    type: 0, //0是驱动，1是分组
    operationType: 0, //0是新增，1是编辑
    id: '', //要编辑的id
    driveId: '', //驱动id针对分组的
    addDriver: () => {},
    getDriverInfo: gettemplat,
    updateDriverInfo: updatetemplate,
    addGroupInfo: addtemplategroup,
    updateGroupInfo: updatetemplategroup,
    getGroupInfo: gettemplategroup,
  });
  let tableParams = reactive({
    driveId: '',
    groupId: '',
  });
  let modalTitle = ref('');
  //是否编辑过
  let isEdit = false;
  watch(
    () => props.info.data,
    (v) => {
      templateInfo = v;
      modalTitle.value = `编辑模板设备-${v.Name}`;
    },
    { immediate: true },
  );

  const [register] = useModal();

  let curType = ref(0);
  let tagFormInfo: any = reactive({
    data: {},
    addTagInfo: addtemplatetag,
    updateTagInfo: updatetemplatetag,
  });
  let typeOptions = reactive([]);
  let driverregesterOPtions = reactive([]);
  let readWriteModeOptions = reactive([]);
  const { createConfirm, createMessage } = useMessage();
  const { t } = useI18n();
  let treeDataPro = ref([]);
  let BasicTableTitle = ref('');
  let loading = ref(false);
  let tableLoading = ref(false);
  let isSubmintLoading = ref(false);
  let tableData = reactive([]);
  const emit = defineEmits(['closeSync']);

  let actionColumn = {
    width: 300,
    title: '操作',
    dataIndex: 'action',
    // slots: { customRender: 'action' },
  };

  // 表格表头
  let columns: BasicColumn[] = [
    {
      title: '变量',
      dataIndex: 'Name',
    },
    {
      title: '地址',
      dataIndex: 'Address',
    },
    {
      width: 77,
      title: '数据类型',
      dataIndex: 'DataTypeCn',
    },
    {
      width: 77,
      title: '读写模式',
      dataIndex: 'ReadWriteModeOptionCn',
    },

    {
      width: 90,
      title: '长度',
      dataIndex: 'Size',
    },
    {
      width: 77,
      title: '是否归档',
      dataIndex: 'ArchiveCn',
    },
    {
      width: 100,
      title: '最大值',
      dataIndex: 'Maximum',
    },
    {
      width: 100,

      title: '最小值',
      dataIndex: 'Minimum',
    },
    {
      title: '变量描述',
      dataIndex: 'Description',
    },
  ];
  const actionList: TreeActionItem[] = [
    {
      show: (node) => {
        return node.Type === 1;
      },
      render: (node) => {
        return h(PlusOutlined, {
          class: 'ml-2',
          onClick: () => {
            handleSetFormType(node, 0);
          },
        });
      },
    },
    {
      show: (node) => {
        return node.Type !== 0;
      },
      render: (node) => {
        return h(EditOutlined, {
          class: 'ml-2',
          onClick: () => {
            handleSetFormType(node, 1);
          },
        });
      },
    },
    {
      show: (node) => {
        return [0, 1].indexOf(node.Type) == -1 && [0, 1].indexOf(node.SystemType) >= 0;
      },
      render: (node: any) => {
        return h(DeleteOutlined, {
          class: 'ml-2',
          onClick: () => {
            createConfirm({
              iconType: 'warning',
              title: () => h('span', '温馨提示'),
              okText: '确认',
              content: () =>
                h(
                  'span',
                  `是否确认删除该${node.Type === 1 ? '驱动' : node.Type === 2 ? '分组' : ''}（${
                    node.title
                  }）`,
                ),
              onOk: async () => {
                try {
                  if (node.Type === 1) {
                    await delDriverInfo([node.Key]);
                  } else {
                    await delGroupInfo([node.Parentkey, node.Key]);
                  }
                  createMessage.success(t('layout.setting.operatingTitle'));
                  initData();
                } catch (error) {}
              },
            });
          },
        });
      },
    },
  ];
  const [registerByDrive, { openModal: openModalByDrive, closeModal: closeModalByDrive }] =
    useModal();
  const [registerByGroup, { openModal: openModalByGroup, closeModal: closeModalByGroup }] =
    useModal();

  const [registerByDetail, { openModal: openModalByDetail, closeModal: closeModalByDetail }] =
    useModal();
  const [registerByCode, { openModal: openModalByCode, closeModal: closeModalByCode }] = useModal();
  const treeRef = ref<Nullable<TreeActionType>>(null);
  const isShowAdd = computed(() => curType.value === 2);

  async function handleVisibleChange(visible) {
    isEdit = false;
    if (visible) {
      await initData(true);
      typeOptions = await getDataType();
      readWriteModeOptions = await getReadWriteMode();
    } else {
      emit('closeSync', {});
    }
  }
  //  封装确认框
  function handleConfirm() {
    return new Promise<boolean>((resolve) => {
      createConfirm({
        iconType: 'warning',
        okText: '同步',
        cancelText: '取消并关闭弹窗',
        title: () => h('span', '温馨提示'),
        content: () => h('span', `模板相关内容已更改，是否同步更新`),
        onOk: async () => {
          try {
            let res: boolean = await handleSubmint();
            resolve(res);
          } catch (_error) {
            resolve(false);
          }
        },
        onCancel: () => {
          resolve(true);
        },
      });
    });
  }

  // 点击关闭：校验是否编辑过，如果有，则提示
  async function handleCloseFunc() {
    if (isEdit) {
      let res = await handleConfirm();
      if (!res) createMessage.error('同步更新失败');
      isEdit = false;
      return res;
    } else {
      isEdit = false;
      return true;
    }
  }

  async function handleSubmint() {
    isSubmintLoading.value = true;
    let isSuccess = false;
    try {
      isSuccess = await savetemplateandupdate([templateInfo.Key]);
      createMessage.success('同步更新成功');
      isSubmintLoading.value = false;
      isEdit = false;
    } catch (error) {
      isSubmintLoading.value = false;
    }
    return isSuccess;
  }
  async function handleGetCode(val) {
    // loading = true;
    console.log(`output->code`, val);
    try {
      await updatetemplatetag([
        tagFormInfo.data.driveId,
        tagFormInfo.data.groupId,
        tagFormInfo.data.Name,
        {
          ...tagFormInfo.data,
          Script: val.code,
          ScaleValue: val.scaleValue,
          ConverterType: +val.converterType,
        },
      ]);
      isEdit = true;
      createMessage.success(t('layout.setting.operatingTitle'));
      tagFormInfo.data = {};
      // loading = false;
      closeModalByCode();
      setTimeout(() => {
        // paginationInfo.data.current = 1;
        setTagList();
      }, 250);
    } catch (error) {
      tagFormInfo.data = {};
      // loading = false;
      closeModalByCode();
    }
  }

  function handelUpdateTree(res) {
    templateInfo.Key = res.Key || templateInfo.Key;
    templateInfo.Name = res.Name || templateInfo.Name;
    isEdit = true;
    closeModalByDrive();
    closeModalByGroup();
    initData();
  }

  function getTree() {
    const tree = unref(treeRef);
    if (!tree) {
      throw new Error('tree is null!');
    }
    return tree;
  }
  function eachTree(treeDatas: any[]) {
    treeDatas.forEach((element) => {
      element.title = element.Name;
      switch (element.Type) {
        case 0:
          element.icon = 'ant-design:home-outlined';
          break;
        case 1:
          element.icon = 'ant-design:database-outlined';
          break;
        case 2:
          element.icon = 'ant-design:bars-outlined';
          break;
        case 3:
          element.icon = 'ant-design:folder-outlined';
          break;
        default:
          break;
      }
      if (element.Children) eachTree(element.Children);
    });
  }
  async function initData(isOpenTree = false) {
    loading.value = true;
    console.log(`output->templateInfo`, templateInfo);
    let resByTree = await gettemplatetree([templateInfo.Key]);
    eachTree(resByTree);
    treeDataPro.value = resByTree || [];
    if (isOpenTree) {
      nextTick(() => {
        getTree().filterByLevel(1);
      });
    }

    loading.value = false;
  }

  function handleAdd() {
    tagFormInfo.data = tableParams;
    openModalByDetail(true, {});
  }

  async function handleCopy(record: Recordable) {
    let params = cloneDeep(record);
    params.Name = `${params.Name}_copy`;
    await addtemplatetag([tableParams.driveId, tableParams.groupId, params]);
    isEdit = true;

    createMessage.success(t('layout.setting.operatingTitle'));
    setTagList();
    // createConfirm({
    //   iconType: 'warning',
    //   title: () => h('span', '温馨提示'),
    //   okText: '确认',
    //   content: () => h('span', `是否确认复制该tag（${params.Name}）`),
    //   onOk: async () => {
    //     try {

    //     } catch (error) {}
    //   },
    // });
  }
  function handleDelete(record: Recordable) {
    createConfirm({
      iconType: 'warning',
      title: () => h('span', '温馨提示'),
      okText: '确认',
      content: () => h('span', `是否确认删除该tag（${record.Name}）`),
      onOk: async () => {
        try {
          await deltemplatetag([tableParams.driveId, tableParams.groupId, record.Name]);
          isEdit = true;

          createMessage.success(t('layout.setting.operatingTitle'));
          setTagList();
        } catch (error) {}
      },
    });
  }
  function handleEdit(record: Recordable) {
    tagFormInfo.data = { ...tableParams, ...record };
    openModalByDetail(true, {});

    console.log('点击了编辑', record);
  }
  function handleCode(record: Recordable) {
    tagFormInfo.data = { ...tableParams, ...record };
    openModalByCode(true, {});
    console.log('点击了打开编译器', record);
  }
  function handlePageChange(page, pageSize) {
    paginationInfo.data.current = page;
    paginationInfo.data.pageSize = pageSize;
    setTagList();
  }
  function handleColumnChange(data: ColumnChangeParam[]) {
    console.log('ColumnChanged', data);
  }

  async function handleTreeSelect(_e, info) {
    BasicTableTitle.value = info.node?.title || '';
    addressExtend.value = info.node?.AddressExtend || 0;
    let { Type, Children = [] } = info.node;
    curType.value = +Type;
    if ((Type === 1 && Children && Children.length > 0) || Type === 2) {
      let targetGroup = Type === 1 ? Children[0] : info.node;

      BasicTableTitle.value = targetGroup.title;
      addressExtend.value = targetGroup.AddressExtend;
      tableParams.groupId = targetGroup.Key;
      tableParams.driveId = targetGroup.Parentkey;
      paginationInfo.data.current = 1;

      setTagList();
      driverregesterOPtions = [];
      let objs = await getdriverregester([targetGroup.Parentkey]);
      for (let key in objs) {
        driverregesterOPtions.push({ value: key, label: key });
      }
    } else {
      BasicTableTitle.value = '';
      addressExtend.value = 0;
      tableData = [];
      tableParams.groupId = '-1';
      tableParams.driveId = '-1';
      driverregesterOPtions = [];
    }
  }
  function handleUpdateTable() {
    closeModalByDetail();
    isEdit = true;
    setTimeout(() => {
      // paginationInfo.data.current = 1;
      setTagList();
    }, 250);
  }
  async function setTagList() {
    try {
      tableLoading.value = true;
      let res = await gettemplatetag([
        {
          DriverKey: tableParams.driveId,
          GroupKey: tableParams.groupId,
          PageNO: paginationInfo.data.current,
          PageSize: paginationInfo.data.pageSize,
        },
      ]);
      paginationInfo.data.total = res.TotalRows;
      tableData = res.Rows.map((item) => {
        item.ArchiveCn = item.Archive ? '是' : '否';
        let targetTypes = typeOptions.filter((v) => v.Value === item.DataType);
        item.DataTypeCn = targetTypes.length > 0 ? targetTypes[0].Key : '';
        let targetReadWriteModes = readWriteModeOptions.filter(
          (v) => v.Value === item.ReadWriteMode,
        );
        item.ReadWriteModeOptionCn =
          targetReadWriteModes.length > 0 ? targetReadWriteModes[0].Key : '';

        return item;
      });
      tableLoading.value = false;
    } catch (error) {
      tableLoading.value = false;
    }
  }
  function handleSetFormType(v, operationType) {
    let { Type, Key, Parentkey } = v;
    formType.operationType = operationType;
    formType.type = operationType === 1 ? Type - 1 : Type;
    formType.id = operationType === 1 ? Key : '';
    formType.driveId = operationType === 1 ? Parentkey : Key;

    if (formType.type === 0) {
      openModalByDrive(true, {});
    } else {
      openModalByGroup(true, {});
    }
  }
</script>

<style scoped lang="less">
  .tag {
    width: 100%;
    position: relative;
    height: 100%;
    background-color: #fff;

    .main-nav {
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      width: 240px;
      height: 100%;
      padding: 8px;
      box-sizing: border-box;
      overflow: auto;
      background-color: rgba(8, 30, 66, 0.04);
      border-radius: 3px;
    }

    .main-content {
      position: relative;
      height: 100%;
      margin-left: 260px;
      overflow: hidden;

      .pagination-box {
        z-index: 9;
        padding: 10px 5px;
        box-sizing: border-box;
        position: absolute;
        width: 100%;
        bottom: 0;
        left: 0;
        right: 0;
        background-color: #fff;
      }
    }

    .main-content::after {
      content: '';
      display: block;
      width: 100%;
      height: 45px;
    }
  }
</style>
